home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C / Libraries / WASTE 1.1 / WEObjects.c < prev    next >
Encoding:
Text File  |  1994-11-01  |  6.8 KB  |  261 lines  |  [TEXT/MPCC]

  1. // { WASTE PROJECT: }
  2. // { Embedded Objects }
  3.  
  4. // { Copyright © 1993-1994 Marco Piovanelli }
  5. // { All Rights Reserved }
  6.  
  7. #include "WASTEIntf.h"
  8.  
  9. extern WELookupTable *_WEObjectHandlerSelectorTable;
  10.  
  11. const short kUnknownObjectType = -1;        // { specifies an object type for which no handlers are installed }
  12. const Point kDefaultObjectSize = {32, 32};    // { default object size (32x32 pixels) }
  13.  
  14. typedef struct WEOHTableElement {
  15.     OSType objectType;            // { 4-letter tag identifying object type }
  16.     WENewObjectProcPtr newHandler;
  17.     WEDisposeObjectProcPtr freeHandler;
  18.     WEDrawObjectProcPtr drawHandler;
  19.     ProcPtr clickHandler;
  20.     ProcPtr cursorHandler;
  21. } WEOHTableElement, *WEOHTableElementPtr, *WEOHTable, **WEOHTablePtr, ***WEOHTableHandle;
  22.  
  23. // { static variables }
  24.  
  25. static WEOHTableHandle sHandlerTable;
  26. static short sHandlerCount;
  27.  
  28. pascal OSType WEGetObjectType(WEObjectDescHandle hObjectDesc)
  29. {
  30.     return (*hObjectDesc)->objectType;
  31. } // { WEGetObjectType }
  32.  
  33. pascal Handle WEGetObjectDataHandle(WEObjectDescHandle hObjectDesc)
  34. {
  35.     return (*hObjectDesc)->objectDataHandle;
  36. } // { WEGetObjectDataHandle }
  37.  
  38. pascal Point WEGetObjectSize(WEObjectDescHandle hObjectDesc)
  39. {
  40.     return (*hObjectDesc)->objectSize;
  41. } // { WEGetObjectSize }
  42.  
  43. pascal WEHandle WEGetObjectOwner(WEObjectDescHandle hObjectDesc)
  44. {
  45.     return (*hObjectDesc)->objectOwner;
  46. } // { WEGetObjectOwner }
  47.  
  48. pascal long WEGetObjectRefCon(WEObjectDescHandle hObjectDesc)
  49. {
  50.     return (*hObjectDesc)->objectRefCon;
  51. } // { WEGetObjectRefCon }
  52.  
  53. pascal void WESetObjectRefCon(WEObjectDescHandle hObjectDesc, long refCon)
  54. {
  55.     (*hObjectDesc)->objectRefCon = refCon;
  56. } // { WESetObjectRefCon }
  57.  
  58. pascal short _WELookupObjectType(OSType objectType)
  59. {
  60.  
  61.     // { look for a WEOHTableElement record for the specified object kind }
  62.     // { in our private object handler table }
  63.  
  64.     WEOHTablePtr pTable;
  65.     short index;
  66.  
  67.     // { do nothing if the Object Handler Table has not been inited yet }
  68.     if (sHandlerTable == nil) return kUnknownObjectType;
  69.  
  70.     // { scan the Object Handler Table looking for a type match }
  71.     pTable = *sHandlerTable;
  72.     for (index = sHandlerCount - 1; index>=0; index--)
  73.     {
  74.         if ((*pTable)[index].objectType == objectType) 
  75.             return index;
  76.     }
  77.     
  78.     return kUnknownObjectType;
  79. } // { _WELookupObjectType }
  80.  
  81. pascal OSErr _WEGetIndObjectType(short index, OSType *objectType)
  82. {
  83.     objectType = 0L;
  84.  
  85.     if (index >= 0 && index < sHandlerCount) 
  86.     {
  87.         *objectType = (**sHandlerTable)[index].objectType;
  88.         return noErr;
  89.     }
  90.     return weUnknownObjectTypeErr;
  91. } // { _WEGetIndObjectType }
  92.  
  93. pascal OSErr _WENewObject(OSType objectType, Handle objectDataHandle, WEHandle hWE,
  94.                     WEObjectDescHandle *hObjectDesc)
  95. {
  96.     WEObjectDescPtr pDesc;
  97.     short index;
  98.     OSErr err;
  99.  
  100.     hObjectDesc = nil;
  101.  
  102.     // { look up the specified object type in the handler table }
  103.     index = _WELookupObjectType(objectType);
  104.  
  105.     // { create a new relocatable block to hold the object descriptor }
  106.     err = _WEAllocate(sizeof(WEObjectDesc), kAllocClear, (Handle *)&hObjectDesc);
  107.     if (err != noErr) return err;
  108.  
  109.     // { lock it down }
  110.     HLock((Handle)hObjectDesc);
  111.     pDesc = (WEObjectDescPtr)*hObjectDesc;
  112.  
  113.     // { fill in the object descriptor }
  114.     pDesc->objectType = objectType;
  115.     pDesc->objectDataHandle = objectDataHandle;
  116.     pDesc->objectSize = kDefaultObjectSize;
  117.     pDesc->objectIndex = index;
  118.     pDesc->objectOwner = hWE;
  119.  
  120.     if (index >= 0) 
  121.     {
  122.         // { call the new handler, if any }
  123.         if ((**sHandlerTable)[index].newHandler != nil) 
  124.         {
  125.             err = (*(*sHandlerTable)[index]->newHandler)(*hObjectDesc, &pDesc->objectSize);
  126.             if (err != noErr) 
  127.             {
  128.                 _WEForgetHandle((Handle *)&hObjectDesc);
  129.                 return err;
  130.             }
  131.         }
  132.     }
  133.     
  134.     // { unlock the object descriptor }
  135.     HUnlock((Handle)hObjectDesc);
  136.  
  137.     // { clear result code }
  138.     return noErr;
  139. } // { _WENewObject }
  140.  
  141. pascal OSErr _WEFreeObject(WEObjectDescHandle hObjectDesc)
  142. {
  143.     WEObjectDescPtr pDesc;
  144.     OSErr retval;
  145.     
  146.     retval = noErr;
  147.  
  148.     // { sanity check: do nothing if we have a null descriptor handle }
  149.     if (hObjectDesc == nil) 
  150.         return nilHandleErr;
  151.  
  152.     // { lock the descriptor record }
  153.     HLock((Handle)hObjectDesc);
  154.     pDesc = *hObjectDesc;
  155.  
  156.     if (pDesc->objectIndex >= 0) 
  157.     {
  158.         // {$IFC WASTE_DEBUG}
  159.         // { sanity check: make sure object kind matches handler kind }
  160.         //    _WEAssert(pDesc->objectType = objectType, 'Object Type Mismatch');
  161.         // {$ENDC}
  162.  
  163.         // { call the dispose handler, if any }
  164.         if ((**sHandlerTable)[pDesc->objectIndex].freeHandler != nil) 
  165.         {
  166.             retval = (*(**sHandlerTable)[pDesc->objectIndex].freeHandler)(hObjectDesc);
  167.             pDesc->objectDataHandle = nil;
  168.         }
  169.     }
  170.     
  171.     // { if object kind is unknown or there's no custom dispose handler, use DisposeHandle }
  172.     _WEForgetHandle(&pDesc->objectDataHandle);
  173.  
  174.     // { finally, dispose of the object descriptor itself }
  175.     DisposeHandle((Handle)hObjectDesc);
  176.  
  177.     return retval;
  178. } // { _WEFreeObject }
  179.  
  180. pascal OSErr _WEDrawObject(WEObjectDescHandle hObjectDesc)
  181. {
  182.     WEObjectDescPtr pDesc;
  183.     Point thePen;
  184.     Rect destRect;
  185.     OSErr retval = noErr;
  186.  
  187.     // { the pen has already been set to the bottom left of the rectangle to draw }
  188.     GetPen(&thePen);
  189.  
  190.     pDesc = *hObjectDesc;
  191.  
  192.     // { calculate the destination rectangle }
  193.     destRect.top = thePen.v - pDesc->objectSize.v;
  194.     destRect.left = thePen.h;
  195.     destRect.bottom = thePen.v;
  196.     destRect.right = thePen.h + pDesc->objectSize.h;
  197.  
  198.     // { calculate the new pen position }
  199.     thePen.h = thePen.h + pDesc->objectSize.h;
  200.  
  201.     if (pDesc->objectIndex >= 0) 
  202.     {
  203.         // {$IFC WASTE_DEBUG}
  204.         // { sanity check: make sure object kind matches handler kind }
  205.         // _WEAssert(pDesc->objectType = objectType, 'Object Type Mismatch');
  206.         // {$ENDC}
  207.  
  208.         // { call the drawing handler, if any }
  209.         if ((**sHandlerTable)[pDesc->objectIndex].drawHandler != nil) 
  210.             retval = (*(**sHandlerTable)[pDesc->objectIndex].drawHandler)(&destRect, hObjectDesc);
  211.     }
  212.  
  213.     // { advance the pen position }
  214.     MoveTo(thePen.h, thePen.v);
  215.  
  216.     return retval;
  217. } // { _WEDrawObject }
  218.  
  219. pascal OSErr WEInstallObjectHandler(OSType objectType, OSType handlerSelector, ProcPtr handler)
  220. {
  221.     short index;
  222.     WEOHTableElement element;
  223.     OSErr err;
  224.  
  225.     // { create the handler table, if it doesn't exist }
  226.     if (sHandlerTable == nil) 
  227.     {
  228.         sHandlerTable = (WEOHTableHandle)NewHandle(0);
  229.         err = MemError();
  230.         if (err != noErr) 
  231.             return err;
  232.     }
  233.  
  234.     // { look for an object handler record for the specified object type }
  235.     index = _WELookupObjectType(objectType);
  236.  
  237.     if (index == kUnknownObjectType) 
  238.     {
  239.  
  240.         // { previously unknown object kind: add a new element to the handler table }
  241.         _WEBlockClr((Ptr)&element, sizeof(element));
  242.         element.objectType = objectType;
  243.         index = sHandlerCount;
  244.         err = _WEInsertSlot((Handle)sHandlerTable, (Ptr)&element, index, sizeof(element));
  245.         if (err != noErr) 
  246.             return err;
  247.  
  248.         // { increment handler count }
  249.         sHandlerCount = index + 1;
  250.  
  251.     }
  252.     
  253.     // { install the handler }
  254.     err = _WESetField(_WEObjectHandlerSelectorTable, handlerSelector, (long *)&handler, 
  255.             (void *)&(*sHandlerTable)[index]);
  256.  
  257.     // { return result code }
  258.     return err;
  259.  
  260. } // { WEInstallObjectHandler }
  261.